1 <!DOCTYPE html PUBLIC
"-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
4 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8">
5 <meta http-equiv=
"Content-Style-Type" content=
"text/css">
7 <meta name=
"Generator" content=
"Cocoa HTML Writer">
8 <meta name=
"CocoaVersion" content=
"1038.25">
9 <style type=
"text/css">
10 p
.p1
{margin: 0.0px 0.0px 0.0px 0.0px; font: 20.0px Helvetica
}
11 p
.p2
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; min-height: 14.0px}
12 p
.p3
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
}
13 p
.p4
{margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica
}
14 p
.p5
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #bf0000}
15 p
.p6
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
}
16 p
.p7
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #007300}
17 p
.p8
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; min-height: 12.0px}
18 p
.p9
{margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco
; color: #0000bf}
19 p
.p10
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #bf0000}
20 p
.p11
{margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica
; color: #0000ee}
21 span
.s1
{color: #0000bf}
22 span
.s2
{color: #000000}
23 span
.s3
{color: #bf0000}
24 span
.s4
{color: #007300}
25 span
.s5
{text-decoration: underline
; color: #0000ee}
26 span
.s6
{font: 12.0px Helvetica
}
27 span
.Apple-tab-span
{white-space:pre
}
31 <p class=
"p1"><b>From words to phrases
</b></p>
32 <p class=
"p2"><br></p>
33 <p class=
"p3">A single pattern by itself is not so exciting. But patterns can be used together to get more complex results.
</p>
34 <p class=
"p2"><br></p>
35 <p class=
"p4"><b>Patterns within list patterns
</b></p>
36 <p class=
"p2"><br></p>
37 <p class=
"p3">We saw list patterns (
<a href=
"../Patterns/Pseq.html"><span class=
"s1">Pseq
</span></a>,
<a href=
"../Patterns/Prand.html"><span class=
"s1">Prand
</span></a>, etc.) that returned numbers from a preset list, either in the order given or rearranged randomly. The list may also include other patterns. When a list pattern encounters another pattern in its list, the inner pattern is
<i>embedded
</i> into the stream. That is, the inner pattern takes over until it runs out of values to return. Then, control returns to the outer list pattern. This is like calling a function in the middle of another function.
</p>
38 <p class=
"p2"><br></p>
39 <p class=
"p3">There is no preset limit to the number of levels of embedding.
</p>
40 <p class=
"p2"><br></p>
41 <p class=
"p3">If a single pattern is like a word, a list pattern that uses other patterns could be more like a sentence or phrase. You can alternate between different behaviors, either in a predictable order as in the example below, or randomly by using one of the random-order list patterns.
</p>
42 <p class=
"p2"><br></p>
43 <p class=
"p5">// Scale segments, in the sequence: up, up, down (repeat)
</p>
45 <p class=
"p6"><span class=
"s1">TempoClock
</span>.default.tempo =
1;
</p>
46 <p class=
"p6">p =
<span class=
"s1">Pbind
</span>(
</p>
47 <p class=
"p7"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span>\degree
<span class=
"s2">,
</span><span class=
"s1">Pseq
</span><span class=
"s2">([
</span></p>
48 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">Pseries
</span>({ rrand(
0,
7) },
1, { rrand(
4,
8) }),
<span class=
"Apple-tab-span"> </span><span class=
"s3">// up (step =
1)
</span></p>
49 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">Pseries
</span>({ rrand(
0,
7) },
1, { rrand(
4,
8) }),
<span class=
"Apple-tab-span"> </span><span class=
"s3">// up (step =
1)
</span></p>
50 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">Pseries
</span>({ rrand(
7,
14) }, -
1, { rrand(
4,
8) })
<span class=
"Apple-tab-span"> </span><span class=
"s3">// down (step = -
1)
</span></p>
51 <p class=
"p6"><span class=
"Apple-tab-span"> </span>],
<span class=
"s1">inf
</span>),
</p>
52 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
0.125</p>
53 <p class=
"p6">).play;
</p>
55 <p class=
"p8"><br></p>
56 <p class=
"p6">p.stop;
</p>
57 <p class=
"p2"><br></p>
58 <p class=
"p2"><br></p>
59 <p class=
"p3">But it gets even more fun -- list patterns don't care whether they're enclosing value patterns (as in the previous example) or event patterns. That means you can write a set of Pbind-style patterns, each one representing a phrase, and string them together. This next example is longer, but that's only because of a larger number of phrase patterns. The structure is very simple, though:
<b>Pxrand([Pbind(), Pmono(), Pmono()...], inf)
</b>. Some of the phrases are written with Pmono to slide between notes.
</p>
60 <p class=
"p2"><br></p>
62 <p class=
"p9">SynthDef
<span class=
"s2">(
</span><span class=
"s4">\bass
</span><span class=
"s2">, {
</span>|freq =
440, gate =
1, amp =
0.5, slideTime =
0.17, ffreq =
1100, width =
0.15,
</p>
63 <p class=
"p9"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>detune =
1.005, preamp =
4|
</p>
64 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s1">var
</span><span class=
"Apple-tab-span"> </span>sig,
</p>
65 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>env =
<span class=
"s1">Env
</span>.adsr(
0.01,
0.3,
0.4,
0.1);
<span class=
"Apple-tab-span"> </span></p>
66 <p class=
"p6"><span class=
"Apple-tab-span"> </span>freq =
<span class=
"s1">Lag
</span>.kr(freq, slideTime);
</p>
67 <p class=
"p6"><span class=
"Apple-tab-span"> </span>sig =
<span class=
"s1">Mix
</span>(
<span class=
"s1">VarSaw
</span>.ar([freq, freq * detune],
0, width, preamp)).distort * amp
</p>
68 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>*
<span class=
"s1">EnvGen
</span>.kr(env, gate, doneAction:
2);
</p>
69 <p class=
"p6"><span class=
"Apple-tab-span"> </span>sig =
<span class=
"s1">LPF
</span>.ar(sig, ffreq);
</p>
70 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s1">Out
</span>.ar(
0, sig !
2)
</p>
71 <p class=
"p6">}).add;
</p>
73 <p class=
"p8"><br></p>
75 <p class=
"p6"><span class=
"s1">TempoClock
</span>.default.tempo =
132/
60;
</p>
76 <p class=
"p6">p =
<span class=
"s1">Pxrand
</span>([
</p>
77 <p class=
"p5"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span><span class=
"s1">Pbind
</span><span class=
"s2">(
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// repeated notes
</p>
78 <p class=
"p7"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\instrument
<span class=
"s2">,
</span>\bass
<span class=
"s2">,
</span></p>
79 <p class=
"p7"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\midinote
<span class=
"s2">,
36,
</span></p>
80 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
<span class=
"s1">Pseq
</span>([
0.75,
0.25,
0.25,
0.25,
0.5],
1),
</p>
81 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\legato
</span>,
<span class=
"s1">Pseq
</span>([
0.9,
0.3,
0.3,
0.3,
0.3],
1),
</p>
82 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\amp
</span>,
0.5,
<span class=
"s4">\detune
</span>,
1.005</p>
83 <p class=
"p6"><span class=
"Apple-tab-span"> </span>),
</p>
84 <p class=
"p5"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span><span class=
"s1">Pmono
</span><span class=
"s2">(
</span><span class=
"s4">\bass
</span><span class=
"s2">,
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// octave jump
</p>
85 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\midinote
</span>,
<span class=
"s1">Pseq
</span>([
36,
48,
36],
1),
</p>
86 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
<span class=
"s1">Pseq
</span>([
0.25,
0.25,
0.5],
1),
</p>
87 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\amp
</span>,
0.5,
<span class=
"s4">\detune
</span>,
1.005</p>
88 <p class=
"p6"><span class=
"Apple-tab-span"> </span>),
</p>
89 <p class=
"p5"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span><span class=
"s1">Pmono
</span><span class=
"s2">(
</span><span class=
"s4">\bass
</span><span class=
"s2">,
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// tritone jump
</p>
90 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\midinote
</span>,
<span class=
"s1">Pseq
</span>([
36,
42,
41,
33],
1),
</p>
91 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
<span class=
"s1">Pseq
</span>([
0.25,
0.25,
0.25,
0.75],
1),
</p>
92 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\amp
</span>,
0.5,
<span class=
"s4">\detune
</span>,
1.005</p>
93 <p class=
"p6"><span class=
"Apple-tab-span"> </span>),
</p>
94 <p class=
"p5"><span class=
"s2"><span class=
"Apple-tab-span"> </span></span><span class=
"s1">Pmono
</span><span class=
"s2">(
</span><span class=
"s4">\bass
</span><span class=
"s2">,
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// diminished triad
</p>
95 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\midinote
</span>,
<span class=
"s1">Pseq
</span>([
36,
39,
36,
42],
1),
</p>
96 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
<span class=
"s1">Pseq
</span>([
0.25,
0.5,
0.25,
0.5],
1),
</p>
97 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\amp
</span>,
0.5,
<span class=
"s4">\detune
</span>,
1.005</p>
98 <p class=
"p6"><span class=
"Apple-tab-span"> </span>)
</p>
99 <p class=
"p6">],
<span class=
"s1">inf
</span>).play(quant:
1);
</p>
101 <p class=
"p8"><br></p>
102 <p class=
"p6">p.stop;
</p>
103 <p class=
"p2"><br></p>
104 <p class=
"p3"><b>Shortcut notation:
</b> Just like you can concatenate arrays with ++, you can also concatenate patterns the same way. Writing
<b>pattern1 ++ pattern2
</b> is the same as writing
<b>Pseq([pattern1, pattern2],
1)
</b>.
</p>
105 <p class=
"p2"><br></p>
106 <p class=
"p2"><br></p>
107 <p class=
"p4"><b>Some ways to string together patterns
</b></p>
108 <p class=
"p2"><br></p>
109 <p class=
"p3"><b>Sequentially:
</b> Each sub-pattern follows the next in the same order every time. Use
<a href=
"../Patterns/Pseq.html"><span class=
"s1">Pseq
</span></a> or
<a href=
"../Patterns/Pser.html"><span class=
"s1">Pser
</span></a>.
</p>
110 <p class=
"p3"><b>Randomized order:
</b> Sub-patterns in completely random order (
<a href=
"../Patterns/Prand.html"><span class=
"s1">Prand
</span></a>), random order with no repeats (
<a href=
"../Patterns/Pxrand.html"><span class=
"s1">Pxrand
</span></a>), or random order according to a set of probabilities (
<a href=
"../Patterns/Pwrand.html"><span class=
"s1">Pwrand
</span></a>).
<a href=
"../Patterns/Pshuf.html"><span class=
"s1">Pshuf
</span></a> creates one random ordering and uses it repeatedly.
</p>
111 <p class=
"p2"><br></p>
112 <p class=
"p3"><b>Direct array indexing:
</b> Patterns can be chosen in arbitrary order by index. This gives you more control than Pwrand. Both
<a href=
"../Patterns/Pindex.html"><span class=
"s1">Pindex
</span></a> and
<a href=
"../Patterns/Pswitch.html"><span class=
"s1">Pswitch
</span></a> can be used for this.
</p>
113 <p class=
"p2"><br></p>
114 <p class=
"p5">// scale degree segments, every fifth choice is odd-numbered only (descending)
</p>
116 <p class=
"p6"><span class=
"s1">var
</span><span class=
"Apple-tab-span"> </span>n =
10,
</p>
117 <p class=
"p6"><span class=
"Apple-tab-span"> </span>scaleSegments =
<span class=
"s1">Array
</span>.fill(n, {
<span class=
"s1">|i|
</span></p>
118 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>if(i.odd) {
</p>
119 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">Pseries
</span>(
11, -
1, rrand(
5,
10))
</p>
120 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>} {
</p>
121 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s1">Pseries
</span>(rrand(-
4,
4),
1, i+
2)
</p>
122 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span>}
</p>
123 <p class=
"p6"><span class=
"Apple-tab-span"> </span>});
</p>
124 <p class=
"p8"><br></p>
125 <p class=
"p6"><span class=
"s1">TempoClock
</span>.default.tempo =
1;
</p>
126 <p class=
"p6">p =
<span class=
"s1">Pbind
</span>(
</p>
127 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\degree
</span>,
<span class=
"s1">Pswitch
</span>(scaleSegments,
<span class=
"s1">Pseq
</span>([
<span class=
"s1">Pwhite
</span>(
0, n-
1,
4),
<span class=
"s1">Pwhite
</span>(
0, n-
1,
1).select(
<span class=
"s1">_
</span>.odd)],
<span class=
"s1">inf
</span>)),
</p>
128 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
0.125</p>
129 <p class=
"p6">).play;
</p>
131 <p class=
"p8"><br></p>
132 <p class=
"p6">p.stop;
</p>
133 <p class=
"p2"><br></p>
134 <p class=
"p3"><b>Finite state machine (Pfsm, Pdfsm):
</b> A finite state machine is a way of associating an item with its possible successors. It is closer to a
"grammar" than purely random selection.
<a href=
"../Patterns/Pfsm.html"><span class=
"s1">Pfsm
</span></a> defines a finite state machine as a set of possible
"entry points," followed by a list of the possible
"states" of the machine and, for each state, a list of the possible states that may follow the current state. States may be single values or patterns, meaning that phrases can be linked to other phrases that
"make sense" in succession (and unwanted transitions can be prevented).
</p>
135 <p class=
"p2"><br></p>
136 <p class=
"p3">If this sounds a bit like a Markov chain, that's because the Pfsm implementation is a special case of a Markov chain where there is an equal probability of choosing the next state from the valid successors. In a Markov chain, the probabilities are weighted according to analysis of a real-world data stream.
</p>
137 <p class=
"p2"><br></p>
138 <p class=
"p3">The Pfsm help file includes very good examples of organizing single values and pattern phrases. Also see
<a href=
"PG_Cookbook06_Phrase_Network.html"><span class=
"s1">PG_Cookbook06_Phrase_Network
</span></a> for an application of Pfsm to generate a corny jazz solo.
</p>
139 <p class=
"p2"><br></p>
140 <p class=
"p3"><span class=
"s5"><a href=
"../Patterns/Pdfsm.html">Pdfsm
</a></span> stands for
"deterministic finite state machine," where there is no random selection.
</p>
141 <p class=
"p2"><br></p>
142 <p class=
"p3"><b>Third-party extension alert:
</b> A good Markov chain implementation for SuperCollider exists in the MathLib quark.
</p>
143 <p class=
"p2"><br></p>
144 <p class=
"p2"><br></p>
145 <p class=
"p3"><b>Library of named sub-patterns
</b></p>
146 <p class=
"p2"><br></p>
147 <p class=
"p3">One very effective way to manage phrases is to make a library, or more precisely
<a href=
"../../Collections/Dictionary.html"><span class=
"s1">Dictionary
</span></a>, of sub-patterns, and then call them up one at a time.
<a href=
"../../Libraries/JITLib/Patterns/Psym.html"><span class=
"s1">Psym
</span></a> is the pattern to do this. The advantage here is that you can store the phrases in a separate place, while the pattern that you actually play is much simpler and describes the musical intent at a much higher level.
</p>
148 <p class=
"p2"><br></p>
149 <p class=
"p5">// Uses the bass SynthDef above
</p>
151 <p class=
"p6">~phrases = (
</p>
152 <p class=
"p6"><span class=
"Apple-tab-span"> </span>repeated:
<span class=
"s1">Pbind
</span>(
</p>
153 <p class=
"p7"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\instrument
<span class=
"s2">,
</span>\bass
<span class=
"s2">,
</span></p>
154 <p class=
"p7"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>\midinote
<span class=
"s2">,
36,
</span></p>
155 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
<span class=
"s1">Pseq
</span>([
0.75,
0.25,
0.25,
0.25,
0.5],
1),
</p>
156 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\legato
</span>,
<span class=
"s1">Pseq
</span>([
0.9,
0.3,
0.3,
0.3,
0.3],
1),
</p>
157 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\amp
</span>,
0.5,
<span class=
"s4">\detune
</span>,
1.005</p>
158 <p class=
"p6"><span class=
"Apple-tab-span"> </span>),
</p>
159 <p class=
"p6"><span class=
"Apple-tab-span"> </span>octave:
<span class=
"s1">Pmono
</span>(
<span class=
"s4">\bass
</span>,
</p>
160 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\midinote
</span>,
<span class=
"s1">Pseq
</span>([
36,
48,
36],
1),
</p>
161 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
<span class=
"s1">Pseq
</span>([
0.25,
0.25,
0.5],
1),
</p>
162 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\amp
</span>,
0.5,
<span class=
"s4">\detune
</span>,
1.005</p>
163 <p class=
"p6"><span class=
"Apple-tab-span"> </span>),
</p>
164 <p class=
"p6"><span class=
"Apple-tab-span"> </span>tritone:
<span class=
"s1">Pmono
</span>(
<span class=
"s4">\bass
</span>,
</p>
165 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\midinote
</span>,
<span class=
"s1">Pseq
</span>([
36,
42,
41,
33],
1),
</p>
166 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
<span class=
"s1">Pseq
</span>([
0.25,
0.25,
0.25,
0.75],
1),
</p>
167 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\amp
</span>,
0.5,
<span class=
"s4">\detune
</span>,
1.005</p>
168 <p class=
"p6"><span class=
"Apple-tab-span"> </span>),
</p>
169 <p class=
"p6"><span class=
"Apple-tab-span"> </span>dim:
<span class=
"s1">Pmono
</span>(
<span class=
"s4">\bass
</span>,
</p>
170 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\midinote
</span>,
<span class=
"s1">Pseq
</span>([
36,
39,
36,
42],
1),
</p>
171 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
<span class=
"s1">Pseq
</span>([
0.25,
0.5,
0.25,
0.5],
1),
</p>
172 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><span class=
"s4">\amp
</span>,
0.5,
<span class=
"s4">\detune
</span>,
1.005</p>
173 <p class=
"p6"><span class=
"Apple-tab-span"> </span>)
</p>
175 <p class=
"p8"><br></p>
176 <p class=
"p6"><span class=
"s1">TempoClock
</span>.default.tempo =
128/
60;
</p>
177 <p class=
"p8"><br></p>
178 <p class=
"p5">// the higher level control pattern is really simple now
</p>
179 <p class=
"p6">p =
<span class=
"s1">Psym
</span>(
<span class=
"s1">Pxrand
</span>(#[repeated, octave, tritone, dim],
<span class=
"s1">inf
</span>), ~phrases).play;
</p>
181 <p class=
"p8"><br></p>
182 <p class=
"p6">p.stop;
</p>
183 <p class=
"p2"><br></p>
184 <p class=
"p3">A complicated pattern with lots of embedding can be hard to read because it's more work to separate note-level details from the larger structure. The pattern choosing the phrases --
<b>Pxrand(#[repeated, octave, tritone, dim], inf)
</b> -- is self-explanatory, however, and Psym fills in the details transparently.
</p>
185 <p class=
"p2"><br></p>
186 <p class=
"p3"><b>Note:
</b> Because of some special handling needed for event patterns, there are two versions of Psym. Psym handles event patterns, while
<a href=
"../../Libraries/JITLib/Patterns/Pnsym.html"><span class=
"s1">Pnsym
</span></a> is for value patterns. Think of it this way: Pbind can be contained within Psym, but it contains Pnsym.
</p>
187 <p class=
"p2"><br></p>
188 <p class=
"p3"><span class=
"Apple-tab-span"> </span>( Psym ( Pbind ( Pnsym ) ) )
</p>
189 <p class=
"p2"><br></p>
190 <p class=
"p3"><b>Good:
</b></p>
191 <p class=
"p3"><span class=
"Apple-tab-span"> </span><b>Psym
</b>(**, (pattern1:
<b>Pbind
</b>(**))
</p>
192 <p class=
"p3"><span class=
"Apple-tab-span"> </span><b>Pbind
</b>(\someValue,
<b>Pnsym
</b>(**, (pattern1: Pwhite(**)))
</p>
193 <p class=
"p2"><br></p>
194 <p class=
"p10"><b>Bad:
</b></p>
195 <p class=
"p3"><span class=
"Apple-tab-span"> </span><b>Pbind
</b>(\someValue,
<b>Psym
</b>(**, (pattern1: Pwhite(**)))
</p>
196 <p class=
"p2"><br></p>
197 <p class=
"p2"><br></p>
198 <p class=
"p3"><b>Switching between patterns for individual values
</b></p>
199 <p class=
"p2"><br></p>
200 <p class=
"p3">In the examples above, if a list pattern encounters another pattern in its input values, the subpattern is embedded in its entirety before the list pattern is allowed to continue. Sometimes you might want to get just one value out of the subpattern, and then choose a different subpattern on the next event. Pswitch, Psym and Pnsym have cousins that do exactly this:
<a href=
"../Patterns/Pswitch1.html"><span class=
"s1">Pswitch1
</span></a>, Psym1 and Pnsym1.
</p>
201 <p class=
"p2"><br></p>
202 <p class=
"p5">// random pitches in two distinct ranges; use a coin toss to decide which for this event
</p>
203 <p class=
"p5">//
70% low,
30% high
</p>
205 <p class=
"p6"><span class=
"s1">TempoClock
</span>.default.tempo =
1;
</p>
206 <p class=
"p6">p =
<span class=
"s1">Pbind
</span>(
</p>
207 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\degree
</span>,
<span class=
"s1">Pswitch1
</span>([
<span class=
"s1">Pwhite
</span>(
7,
14,
<span class=
"s1">inf
</span>),
<span class=
"s1">Pwhite
</span>(-
7,
0,
<span class=
"s1">inf
</span>)],
<span class=
"s1">Pfunc
</span> {
0.7.coin.binaryValue }),
</p>
208 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
0.25</p>
209 <p class=
"p6">).play;
</p>
211 <p class=
"p8"><br></p>
212 <p class=
"p6">p.stop;
</p>
213 <p class=
"p2"><br></p>
214 <p class=
"p3">Compare to the following:
</p>
215 <p class=
"p2"><br></p>
217 <p class=
"p6">p =
<span class=
"s1">Pbind
</span>(
</p>
218 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\degree
</span>,
<span class=
"s1">Pswitch
</span>([
<span class=
"s1">Pwhite
</span>(
7,
14,
<span class=
"s1">inf
</span>),
<span class=
"s1">Pwhite
</span>(-
7,
0,
<span class=
"s1">inf
</span>)],
<span class=
"s1">Pfunc
</span> {
0.7.coin.binaryValue }),
</p>
219 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
0.25</p>
220 <p class=
"p6">).play;
</p>
222 <p class=
"p8"><br></p>
223 <p class=
"p6">p.stop;
</p>
224 <p class=
"p2"><br></p>
225 <p class=
"p3">With Pswitch, one of the items is chosen from the list and keeps playing until it's finished. But the length of both Pwhite patterns is infinite, so whichever one is chosen first retains control. Pswitch1 does the coin toss on every event and embeds just one item.
</p>
226 <p class=
"p2"><br></p>
227 <p class=
"p3">Psym1 and Pnsym1 behave similarly, choosing the name to look up the pattern for each event.
</p>
228 <p class=
"p2"><br></p>
229 <p class=
"p3"><b>Related: Conditional patterns
</b></p>
230 <p class=
"p2"><br></p>
231 <p class=
"p3"><span class=
"s5"><a href=
"../Patterns/Pif.html">Pif
</a></span> supports this kind of structure: If the next value from a Boolean pattern is true, return the next item from pattern A, otherwise take it from pattern B. Another way to write the Pswitch1 example is to use a Boolean test directly on Pwhite, instead of writing a Pfunc for the coin toss. This might be clearer to read. However, this works only when there are two alternatives. Pswitch1 and Psym1 allow any number of choices.
</p>
232 <p class=
"p2"><br></p>
234 <p class=
"p6"><span class=
"s1">TempoClock
</span>.default.tempo =
1;
</p>
235 <p class=
"p6">p =
<span class=
"s1">Pbind
</span>(
</p>
236 <p class=
"p5"><span class=
"s2"><span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span></span>// translation: if(
0.7.coin) { rrand(-
7,
0) } { rrand(
7,
14 }
</p>
237 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\degree
</span>,
<span class=
"s1">Pif
</span>(
<span class=
"s1">Pwhite
</span>(
0.0,
1.0,
<span class=
"s1">inf
</span>)
< 0.7,
<span class=
"s1">Pwhite
</span>(-
7,
0,
<span class=
"s1">inf
</span>),
<span class=
"s1">Pwhite
</span>(
7,
14,
<span class=
"s1">inf
</span>)),
<span class=
"Apple-converted-space"> </span></p>
238 <p class=
"p6"><span class=
"Apple-tab-span"> </span><span class=
"s4">\dur
</span>,
0.25</p>
239 <p class=
"p6">).play;
</p>
241 <p class=
"p8"><br></p>
242 <p class=
"p6">p.stop;
</p>
243 <p class=
"p2"><br></p>
244 <p class=
"p3">We will see in
<a href=
"PG_06e_Language_Control.html"><span class=
"s1">PG_06e_Language_Control
</span></a> that Pif can be used on values that were previously calculated in the Pbind. It adds considerably to the intelligence Pbind can manage, when its value streams are aware of other values in the event.
</p>
245 <p class=
"p2"><br></p>
246 <p class=
"p2"><br></p>
247 <p class=
"p11"><span class=
"s2">Previous:
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><a href=
"PG_03_What_Is_Pbind.html"><span class=
"s6">PG_03_What_Is_Pbind
</span></a></span></p>
248 <p class=
"p11"><span class=
"s2">Next:
<span class=
"Apple-tab-span"> </span><span class=
"Apple-tab-span"> </span><a href=
"PG_05_Math_on_Patterns.html"><span class=
"s6">PG_05_Math_on_Patterns
</span></a></span></p>